package com.lrs.java.j2se_advanced.script;

import java.io.FileReader;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class ScriptTest {
	static ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
	
	public static void main(String[] args) throws Exception {
//		testUsingJDKClasses();
//		testScriptInterface();
//		testInvokeScriptMethod();
		testInvokeLib();
		
	}
	
	/**
	 * 演示脚本语言如何使用JDK平台下的类,调用一个JDK平台的Swing窗口
	 *
	 * @param engine ScriptEngine实例
	 * @return void
	 * */
	private static void testUsingJDKClasses() throws Exception {
		// Packages是脚本语言里的一个全局变量,专用于访问JDK的package
		String js = "function doSwing(t){var f=new Packages.javax.swing.JFrame(t);f.setSize(400,300);f.setVisible(true);}";
		engine.eval(js);
		// Invocable 接口: 允许java平台调用脚本程序中的函数或方法
		Invocable inv = (Invocable) engine;
		// invokeFunction()中的第一个参数就是被调用的脚本程序中的函数，第二个参数是传递给被调用函数的参数；
		inv.invokeFunction("doSwing", "Scripting Swing");
	}
	
	
	/**
	 * 演示脚本语言如何实现Java的接口,启动线程来运行script提供的方法
	 *
	 * @param engine ScriptEngine实例
	 * @return void
	 * */	
	private static void testScriptInterface() throws ScriptException {
		String script = "var obj = new Object(); obj.run = function() { println('run method called'); }";
		engine.eval(script);
		Object obj = engine.get("obj");
		Invocable inv = (Invocable) engine;
		
		Runnable r = inv.getInterface(obj, Runnable.class);
		Thread th = new Thread(r);
		th.start();
	}

	
	/**
	 * 演示如何在Java中调用脚本语言的方法，通过JDK平台给script的方法中的形参赋值
	 *
	 * @param engine ScriptEngine实例
	 * @return void
	 * */		
	private static void testInvokeScriptMethod() throws Exception {
		String script = "function helloFunction(name) { return 'Hello everybody,' + name;}";
		engine.eval(script);
		Invocable inv = (Invocable) engine;
		String res = (String) inv.invokeFunction("helloFunction", "Scripting");
		System.out.println("res:" + res);
	}

	private static void testInvokeLib() throws Exception {
	
//		BufferedReader reader = new BufferedReader(new InputStreamReader(
//				Thread.currentThread().getContextClassLoader().getResourceAsStream("merge.js"))
//			);
		FileReader reader = new FileReader("merge.js");
		int str;
		while((str=reader.read()) != -1) {
			System.out.println(str);
		}
		
		
		String settings = "{ validate: false, limit: 5, name: 'foo' }";
		String options = "{ validate: true, name: 'bar'}";
		
//		engine.eval(reader);
//		engine.eval("function merge(jsonbject1, jsonbject2) {var resultJsonObject = {};for ( var attr in jsonbject1) {resultJsonObject[attr] = jsonbject1[attr];}for( var attr in jsonbject2){resultJsonObject[attr] = jsonbject2[attr];}return resultJsonObject;};");
//		Invocable inv = (Invocable) engine;
//		String res = (String) inv.invokeFunction("merge", settings, options);
//		System.out.println("res:" + res);
	}
	

}
